#ifndef ZENENGINE_H
#define ZENENGINE_H

#define DIRECTINPUT_VERSION  0x0800

#include <windows.h>
#include <d3d8.h>
#include <d3dx8.h>
#include <d3d8types.h>
#include <dinput.h>

enum GraphMode {D3, D2};

#define RENDER_BOTH	0
#define RENDER_D3D	1
#define RENDER_GDI	2
#define MATCH(a,b) (!strcmp(a,b))
#define CUSTOM_ZENVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)

struct ZENVERTEX
{
	float		x,  y,  z;
	D3DCOLOR	DiffuseColor;
	float		tu, tv;
};

class CZenEngine
{
public:
	static LPDIRECT3D8				m_pD3D;
	static LPDIRECT3DDEVICE8		m_pDevice;
	static LPDIRECT3DSURFACE8		m_pBackSurface;
	static D3DPRESENT_PARAMETERS	m_SavedPresParams;
	static GraphMode				m_Mode;

	static LPDIRECT3DSURFACE8		m_pD3DBitmapSurf;
	static HBITMAP					m_hGDIBitmap;
	static HDC						m_hGDIBitmapDC;	
	static int						m_nRenderMode;
	
	static int						m_nDeviceWidth;
	static int						m_nDeviceHeight;

	static INT64					m_n64Frequency;
	static int						m_nFrameCount;
	static int						m_nFrameRate; 
	static float					m_fFrameDeviance;

	static LPDIRECT3DSURFACE8		m_pAlphabetSurface2;
	static int						m_nAlphabetWidth;
	static int						m_nAlphabetHeight;
	static int						m_nAlphabetLetterWidth;
	static int						m_nAlphabetLetterHeight;
	static int						m_nAlphabetLettersPerRow;
	static BOOL		 				m_bAlphabetsLoaded;
	static LPDIRECT3DSURFACE8		m_pAlphabetSurface;
	static LPDIRECT3DVERTEXBUFFER8	m_pVB;
	static LPDIRECTINPUT8			m_pDI;

	static LPDIRECT3DTEXTURE8		m_pDefaultTexture;
	static LPDIRECT3DTEXTURE8		m_pTexture;
	static int						m_RefCount;

public:
	CZenEngine();
	~CZenEngine();

	void SetError( char* String );
	HRESULT InitDirect3DDevice( HWND hWndTarget, int Width, int Height, BOOL bWindowed, D3DFORMAT FullScreenFormat, LPDIRECT3D8 pD3D, LPDIRECT3DDEVICE8* ppDevice );

	//Opdracht 1
	void SetPixel32( int x, int y, DWORD Color, int Pitch, DWORD* pData );
	void Rectangle32( D3DRECT* pRect, DWORD Color, int Pitch, DWORD* pData );
	void Rectangle32Fast( D3DRECT* pRect, DWORD Color, LPDIRECT3DDEVICE8 pDevice );

	//Opdracht 2
	HRESULT LoadBitmapToSurface( char* PathName, LPDIRECT3DSURFACE8* ppSurface,
								 LPDIRECT3DDEVICE8 pDevice );
	HRESULT ValidateDevice();
	HRESULT RestoreGraphics();
	HRESULT CopyDCToSurface( LPDIRECT3DSURFACE8 pDestSurf, POINT* pDestPoint, 
							 HDC hDCSource, HBITMAP hDibSection, RECT* pSrcRect, 
							 COLORREF ColorKey );
	HDC CreateD3DCompatibleDC( int Width, int Height, HBITMAP* phDibSection );
	void DeleteD3DCompatibleDC( HDC hDC, HBITMAP hDibSection );

	//opdracht 3
	HRESULT CopySurfaceToSurface( RECT* pSourceRect, LPDIRECT3DSURFACE8 pSourceSurf, POINT* pDestPoint, 
								LPDIRECT3DSURFACE8 pDestSurf, BOOL bTransparent, D3DCOLOR ColorKey );
	void Pause( int Milliseconds );
	float GetNumTicksPerMs();
	void FrameCount();
	HRESULT InitTiming();
	HRESULT LoadAlphabet( char* strPathName, char* strPathName2,int LetterWidth, int LetterHeight );
	HRESULT UnloadAlphabet();
	void PrintChar( int x, int y, char Character, BOOL bTransparent, 
						D3DCOLOR ColorKey, DWORD* pDestData, int DestPitch, bool fontHighlight = false);
	void PrintString( int x, int y, char* String, BOOL bTransparent, 
					D3DCOLOR ColorKey, DWORD* pDestData, int DestPitch, bool fontHighlight= false );
	void PrintFrameRate( int x, int y, BOOL bTransparent, D3DCOLOR ColorKey, 
						 DWORD* pDestData, int DestPitch );
	void CZenEngine::SetGraphMode(GraphMode mode);

	//opdracht 4
	int CZenEngine::ParseStringForNumber( char* pString );

	//opdracht 5
	HRESULT CreateViewport();
	void SetProjectionMatrix();
	HRESULT InitializeInput(HINSTANCE hInstance);
	HRESULT CZenEngine::ShutdownInput();

	//opdracht 6
};

#endif
